module DES_Encryption(CLK_50, VGA_R, VGA_B, VGA_G, VGA_HS, VGA_VS, VGA_SYNC_N, VGA_BLANK_N, VGA_CLK, rst,PS2_DAT,PS2_CLK,check,scan_ready,SW,SW2);
		parameter n0=8'h45;
		parameter n1=8'h16;
		parameter n2=8'h1e;
		parameter n3=8'h26;
		parameter n4=8'h25;
		parameter n5=8'h2e;
		parameter n6=8'h36;
		parameter n7=8'h3d;
		parameter n8=8'h3e;
		parameter n9=8'h46;
		parameter A=8'h1c;
		parameter B=8'h32;
		parameter C=8'h21;
		parameter D=8'h23;
		parameter E=8'h24;
		parameter F=8'h2b;
		parameter G=8'h34;
		parameter H=8'h33;
		parameter I=8'h43;
		parameter J=8'h3b;
		parameter K=8'h42;
		parameter L=8'h4b;
		parameter M=8'h3a;
		parameter N=8'h31;
		parameter O=8'h44;
		parameter P=8'h4d;
		parameter Q=8'h15;
		parameter R=8'h2d;
		parameter S=8'h1b;
		parameter T=8'h2c;
		parameter U=8'h3c;
		parameter V=8'h2a;
		parameter W=8'h1d;
		parameter X=8'h22;
		parameter Y=8'h35;
		parameter Z=8'h1a;
		parameter SPACE=8'h29;
		wire key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16;
		wire key21,key22,key23,key24,key25,key26,key27,key28,key29,key210,key211,key212,key213,key214,key215,key216;
		input SW,SW2;
    output [7:0] VGA_R, VGA_B, VGA_G;
    output VGA_HS, VGA_VS, VGA_BLANK_N, VGA_CLK, VGA_SYNC_N;
    input CLK_50, rst;
	 input PS2_DAT,PS2_CLK;
    wire CLK108;
	 wire ctrl;
	 wire [16:1]mctr;
	 wire [16:1]kctr;
	 wire [16:1]ectr;
	 wire [16:1]k2ctr;
	 wire [16:1]dectr;
    clock108(rst, CLK_50, CLK_108, locked);
	 output scan_ready;
	 wire read;
	 wire [7:0]scan_code;
	 keyboard_input(CLK_50,PS2_DAT,PS2_CLK,scan_code,scan_ready,read);
	 output [7:0] check = scan_code;
	 //message
	 reg [71:0]m;
	// assign m = {H,E,L,L,O,SPACE,M,R}; //working form
	 //key
	 reg[71:0]k;
	 reg[71:0]k2;
	 
	 
	 //generate keys
	 generate_keys(k[71:8],key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16);
	 //generate keys2
	 generate_keys(k2[71:8],key21,key22,key23,key24,key25,key26,key27,key28,key29,key210,key211,key212,key213,key214,key215,key216);
						
	//encode
	wire [63:0]encoded_msg;
	encode encrypt(m[71:8],encoded_msg,key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16);
	//fix encoded_msg
	wire [127:0]encoded_disp;
	hex_to_char(encoded_msg[63:60],encoded_disp[127:120]);
	hex_to_char(encoded_msg[59:56],encoded_disp[119:112]);
	hex_to_char(encoded_msg[55:52],encoded_disp[111:104]);
	hex_to_char(encoded_msg[51:48],encoded_disp[103:96]);
	hex_to_char(encoded_msg[47:44],encoded_disp[95:88]);
	hex_to_char(encoded_msg[43:40],encoded_disp[87:80]);
	hex_to_char(encoded_msg[39:36],encoded_disp[79:72]);
	hex_to_char(encoded_msg[35:32],encoded_disp[71:64]);
	hex_to_char(encoded_msg[31:28],encoded_disp[63:56]);
	hex_to_char(encoded_msg[27:24],encoded_disp[55:48]);
	hex_to_char(encoded_msg[23:20],encoded_disp[47:40]);
	hex_to_char(encoded_msg[19:14],encoded_disp[39:32]);
	hex_to_char(encoded_msg[15:10],encoded_disp[31:24]);
	hex_to_char(encoded_msg[11:8],encoded_disp[23:16]);
	hex_to_char(encoded_msg[7:4],encoded_disp[15:8]);
	hex_to_char(encoded_msg[3:0],encoded_disp[7:0]);
	
	wire [63:0]decoded_msg;
	//Decode
	encode decrypt(encoded_msg,decoded_msg,key216,key215,key214,key213,key212,key211,key210,key29,key28,key27,key26,key25,key24,key23,key22,key21);
	
		
		
		
	 //Input control
	 reg [7:0] temp,temp2,temp3;
	 reg [31:0]count = 0;
	 reg [31:0]count2 = 0;
	 reg [31:0]count3 = 0;
	 reg [2:0]St,St2,St3;
	 parameter WAIT = 3'b000,
				  DRAW = 3'b001,
				  TRANS = 3'b010,
				  DELAY = 3'b100;
	//Message in
	always@(posedge CLK_50)
		if(SW&&!SW2)
		case(St)
			WAIT:
				if(temp != m[15:8])
					St <= DELAY;
				else
					temp <= scan_code;
			DRAW:begin
					m[7:0] <= temp;
					St <= TRANS;
				end
			TRANS:begin
				m <= (m<<8);
				St <= WAIT;
			end
			DELAY:
				if(count < 25000000)
					count <= count + 1;
				else begin
					count <= 0;
					St <= DRAW;
				end
		endcase
		//k1
		always@(posedge CLK_50)
		if(!SW&&SW2)
		case(St2)
			WAIT:
				if(temp2 != k[15:8])
					St2 <= DELAY;
				else
					temp2 <= scan_code;
			DRAW:begin
					k[7:0] <= temp2;
					St2 <= TRANS;
				end
			TRANS:begin
				k <= (k<<8);
				St2 <= WAIT;
			end
			DELAY:
				if(count2 < 25000000)
					count2 <= count2 + 1;
				else begin
					count2 <= 0;
					St2 <= DRAW;
				end
		endcase		
		//k2	
		always@(posedge CLK_50)
		if(SW&&SW2)
		case(St3)
			WAIT:
				if(temp3 != k2[15:8])
					St3 <= DELAY;
				else
					temp3 <= scan_code;
			DRAW:begin
					k2[7:0] <= temp3;
					St3 <= TRANS;
				end
			TRANS:begin
				k2 <= (k2<<8);
				St3 <= WAIT;
			end
			DELAY:
				if(count3 < 25000000)
					count3 <= count3 + 1;
				else begin
					count3 <= 0;
					St3 <= DRAW;
				end
		endcase
		
		
			 
    wire hblank, vblank, clkLine, blank;
    H_SYNC(CLK_108, VGA_HS, hblank, clkLine);
    V_SYNC(clkLine, VGA_VS, vblank);
    color(ctrl,CLK_108, VGA_R, VGA_B, VGA_G);
	 assign ctrl = mctr[1]||mctr[2]||mctr[3]||mctr[4]||mctr[5]||mctr[6]||mctr[7]||mctr[8]||mctr[9]||mctr[10]||mctr[11]||mctr[12]||mctr[13]||mctr[14]||mctr[15]||mctr[16]||
						kctr[1]||kctr[2]||kctr[3]||kctr[4]||kctr[5]||kctr[6]||kctr[7]||kctr[8]||kctr[9]||kctr[10]||kctr[11]||kctr[12]||kctr[13]||kctr[14]||kctr[15]||kctr[16]||
						ectr[1]||ectr[2]||ectr[3]||ectr[4]||ectr[5]||ectr[6]||ectr[7]||ectr[8]||ectr[9]||ectr[10]||ectr[11]||ectr[12]||ectr[13]||ectr[14]||ectr[15]||ectr[16]||
						k2ctr[1]||k2ctr[2]||k2ctr[3]||k2ctr[4]||k2ctr[5]||k2ctr[6]||k2ctr[7]||k2ctr[8]||k2ctr[9]||k2ctr[10]||k2ctr[11]||k2ctr[12]||k2ctr[13]||k2ctr[14]||k2ctr[15]||k2ctr[16]||
						dectr[1]||dectr[2]||dectr[3]||dectr[4]||dectr[5]||dectr[6]||dectr[7]||dectr[8]||dectr[9]||dectr[10]||dectr[11]||dectr[12]||dectr[13]||dectr[14]||dectr[15]||dectr[16];
	 
	 //Message characters
	 color_control message9(CLK_108, mctr[9],(32'd336),(32'd210),m[71:64]);
	 color_control message10(CLK_108, mctr[10],(32'd353),(32'd210),m[63:56]);
	 color_control message11(CLK_108, mctr[11],(32'd370),(32'd210),m[55:48]);
	 color_control message12(CLK_108, mctr[12],(32'd387),(32'd210),m[47:40]);
	 color_control message13(CLK_108, mctr[13],(32'd404),(32'd210),m[39:32]);
	 color_control message14(CLK_108, mctr[14],(32'd421),(32'd210),m[31:24]);
	 color_control message15(CLK_108, mctr[15],(32'd438),(32'd210),m[23:16]);
	 color_control message16(CLK_108, mctr[16],(32'd455),(32'd210),m[15:8]);
	 
	 
	 //Key characters
	 color_control key_char1(CLK_108, kctr[1],(32'd200),(32'd240),k[71:64]);
	 color_control key_char2(CLK_108, kctr[2],(32'd217),(32'd240),k[63:56]);
	 color_control key_char3(CLK_108, kctr[3],(32'd234),(32'd240),k[55:48]);
	 color_control key_char4(CLK_108, kctr[4],(32'd251),(32'd240),k[47:40]);
	 color_control key_char5(CLK_108, kctr[5],(32'd268),(32'd240),k[39:32]);
	 color_control key_char6(CLK_108, kctr[6],(32'd285),(32'd240),k[31:24]);
	 color_control key_char7(CLK_108, kctr[7],(32'd302),(32'd240),k[23:16]);
	 color_control key_char8(CLK_108, kctr[8],(32'd319),(32'd240),k[15:8]);
	 
	 //Encoded characters
	 color_control encoded_char1(CLK_108, ectr[1],(32'd200),(32'd270),encoded_disp[127:120]);
	 color_control encoded_char2(CLK_108, ectr[2],(32'd217),(32'd270),encoded_disp[119:112]);
	 color_control encoded_char3(CLK_108, ectr[3],(32'd234),(32'd270),encoded_disp[111:104]);
	 color_control encoded_char4(CLK_108, ectr[4],(32'd251),(32'd270),encoded_disp[103:96]);
	 color_control encoded_char5(CLK_108, ectr[5],(32'd268),(32'd270),encoded_disp[95:88]);
	 color_control encoded_char6(CLK_108, ectr[6],(32'd285),(32'd270),encoded_disp[87:80]);
	 color_control encoded_char7(CLK_108, ectr[7],(32'd302),(32'd270),encoded_disp[79:72]);
	 color_control encoded_char8(CLK_108, ectr[8],(32'd319),(32'd270),encoded_disp[71:64]);
	 color_control encoded_char9(CLK_108, ectr[9],(32'd336),(32'd270),encoded_disp[63:56]);
	 color_control encoded_char10(CLK_108, ectr[10],(32'd353),(32'd270),encoded_disp[55:48]);
	 color_control encoded_char11(CLK_108, ectr[11],(32'd370),(32'd270),encoded_disp[47:40]);
	 color_control encoded_char12(CLK_108, ectr[12],(32'd387),(32'd270),encoded_disp[39:32]);
	 color_control encoded_char13(CLK_108, ectr[13],(32'd404),(32'd270),encoded_disp[31:24]);
	 color_control encoded_char14(CLK_108, ectr[14],(32'd421),(32'd270),encoded_disp[23:16]);
	 color_control encoded_char15(CLK_108, ectr[15],(32'd438),(32'd270),encoded_disp[15:8]);
	 color_control encoded_char16(CLK_108, ectr[16],(32'd455),(32'd270),encoded_disp[7:0]);
	 
	 //Key characters 2.0
	 color_control key2_char1(CLK_108, k2ctr[1],(32'd200),(32'd300),k2[71:64]);
	 color_control key2_char2(CLK_108, k2ctr[2],(32'd217),(32'd300),k2[63:56]);
	 color_control key2_char3(CLK_108, k2ctr[3],(32'd234),(32'd300),k2[55:48]);
	 color_control key2_char4(CLK_108, k2ctr[4],(32'd251),(32'd300),k2[47:40]);
	 color_control key2_char5(CLK_108, k2ctr[5],(32'd268),(32'd300),k2[39:32]);
	 color_control key2_char6(CLK_108, k2ctr[6],(32'd285),(32'd300),k2[31:24]);
	 color_control key2_char7(CLK_108, k2ctr[7],(32'd302),(32'd300),k2[23:16]);
	 color_control key2_char8(CLK_108, k2ctr[8],(32'd319),(32'd300),k2[15:8]);
	 
	 //Decoded characters
	 color_control encoded2_char9(CLK_108, dectr[9],(32'd336),(32'd330),decoded_msg[63:56]);
	 color_control encoded2_char10(CLK_108, dectr[10],(32'd353),(32'd330),decoded_msg[55:48]);
	 color_control encoded2_char11(CLK_108, dectr[11],(32'd370),(32'd330),decoded_msg[47:40]);
	 color_control encoded2_char12(CLK_108, dectr[12],(32'd387),(32'd330),decoded_msg[39:32]);
	 color_control encoded2_char13(CLK_108, dectr[13],(32'd404),(32'd330),decoded_msg[31:24]);
	 color_control encoded2_char14(CLK_108, dectr[14],(32'd421),(32'd330),decoded_msg[23:16]);
	 color_control encoded2_char15(CLK_108, dectr[15],(32'd438),(32'd330),decoded_msg[15:8]);
	 color_control encoded2_char16(CLK_108, dectr[16],(32'd455),(32'd330),decoded_msg[7:0]);
	 
	 
	 
    assign VGA_CLK = CLK_108;
    assign VGA_BLANK_N = VGA_VS&VGA_HS;
    assign VGA_SYNC_N = 1'b0;

endmodule  
module color(ctr,clk, red, blue, green);

    input clk;
    output [7:0] red, blue, green;
	 reg [7:0] red, blue, green;
	 input ctr;
	 always@(*)
		if (ctr == 1'b0)begin
			red <= 8'd255;
			blue <= 8'd255;
			green <= 8'd255;
		end
		else begin
			red <= 8'd0;
			blue <= 8'd0;
			green <= 8'd0;
		end

endmodule
////////////////////////////////////////////////////////////////////////////////////////////
module color_control(clk, ctr,startX,startY,letter);
	input clk;
	input [31:0]startX,startY;
	output ctr;
	input [7:0]letter;
	reg [31:0] countX=0; 
	reg [31:0] countY=0; 
	reg [11:0]index = 12'd255;
	reg hdone;
	wire[15:0]c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15;
	letters(letter,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15);
	wire [255:0]char;
	assign char = {c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15};
	reg color;
	always@(posedge clk) begin
		if (countX==1688) begin
			countX<=0;
			hdone<=1;
		end else begin
			countX<=countX+1;
			hdone<=0;
		end
	end
	always@(posedge clk) begin
		if (countY==1067) begin
			countY<=0;
		end else if (hdone) begin
			countY<=countY+1;
		end
	end
	
	parameter XXX = 17;
	wire [1:0] textBox;
	assign textBox[0] = ((countX>startX)&&(countX<(startX+XXX)));
	assign textBox[1] = ((countY>startY)&&(countY<(startY+33)));
	always@(posedge clk)
		if(textBox==2'b11)begin
			color <= char[index];
			index <= index - 1;
		end
		else if (index == 12'd0)
			index <= 12'd255;
	
	assign ctr = ((countX>startX&&countX<(startX+XXX))&&(countY>startY&&countY<(startY+17)))?color:1'b0;
	
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////
//DES encryption 
module encode(m,out,key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16);
input [64:1]m;
input [47:0]key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16;
output [64:1]out;
wire [64:1]t;
wire [32:1]L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13,L14,L15,L16;
wire [32:1]R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16;
wire [32:1]result1,result2,result3,result4,result5,result6,result7,result8,result9,result10,result11,result12,result13,result14,result15,result16;
						
assign L0 = {m[58],m[50],m[42],m[34],m[26],m[18],m[10],m[2],m[60],m[52],m[44],m[36],m[28],m[20],m[12],m[4],
			m[62],m[54],m[46],m[38],m[30],m[22],m[14],m[6],m[64],m[56],m[48],m[40],m[32],m[24],m[16],m[8]};
assign R0 = {m[57],m[49],m[41],m[33],m[25],m[17],m[9],m[1],m[59],m[51],m[43],m[35],m[27],m[19],m[11],m[3],
			m[61],m[53],m[45],m[37],m[29],m[21],m[13],m[5],m[63],m[55],m[47],m[39],m[31],m[23],m[15],m[7]};
f k1(R0,key1,result1);
f k2(R1,key2,result2);
f k3(R2,key3,result3);
f k4(R3,key4,result4);
f k5(R4,key5,result5);
f k6(R5,key6,result6);
f k7(R6,key7,result7);
f k8(R7,key8,result8);
f k9(R8,key9,result9);
f k10(R9,key10,result10);
f k11(R10,key11,result11);
f k12(R11,key12,result12);
f k13(R12,key13,result13);
f k14(R13,key14,result14);
f k15(R14,key15,result15);
f k16(R15,key16,result16);
////
assign L1 = R0;
assign L2 = R1;
assign L3 = R2;
assign L4 = R3;
assign L5 = R4;
assign L6 = R5;
assign L7 = R6;
assign L8 = R7;
assign L9 = R8;
assign L10 = R9;
assign L11 = R10;
assign L12 = R11;
assign L13 = R12;
assign L14 = R13;
assign L15 = R14;
assign L16 = R15;
////
assign R1 = L0^result1;
assign R2 = L1^result2;
assign R3 = L2^result3;
assign R4 = L3^result4;
assign R5 = L4^result5;
assign R6 = L5^result6;
assign R7 = L6^result7;
assign R8 = L7^result8;
assign R9 = L8^result9;
assign R10 = L9^result10;
assign R11 = L10^result11;
assign R12 = L11^result12;
assign R13 = L12^result13;
assign R14 = L13^result14;
assign R15 = L14^result15;
assign R16 = L15^result16;
////
assign t = {R16,L16};
assign out = {t[40],t[8],t[48],t[16],t[56],t[24],t[64],t[32],
			  t[39],t[7],t[47],t[15],t[55],t[23],t[63],t[31],
			  t[38],t[6],t[46],t[14],t[54],t[22],t[62],t[30],
			  t[37],t[5],t[45],t[13],t[53],t[21],t[61],t[29],
			  t[36],t[4],t[44],t[12],t[52],t[20],t[60],t[28],
			  t[35],t[3],t[43],t[11],t[51],t[19],t[59],t[27],
			  t[34],t[2],t[42],t[10],t[50],t[18],t[58],t[26],
			  t[33],t[1],t[41],t[9], t[49],t[17],t[57],t[25]};//final permutation
endmodule

module f(in, key, result);
	input [32:1]in;
	input [48:1]key;
	wire [48:1] E, B;
	wire [4:1]S1,S2,S3,S4,S5,S6,S7,S8;
	wire [32:1]S;
	output [32:1]result;
	assign E = {in[32],in[1],in[2],in[3],in[4],in[5],in[4],in[5],in[6],in[7],in[8],in[9],in[8],in[9],in[10],in[11],in[12],in[13],
					in[12],in[13],in[14],in[15],in[16],in[17],in[16],in[17],in[18],in[19],in[20],in[21],in[20],in[21],in[22],in[23],
					in[24],in[25],in[24],in[25],in[26],in[27],in[28],in[29],in[28],in[29],in[30],in[31],in[32],in[1]};
	assign B = key^E;
	lookup(B[48:43],(4'd1),S1);
	lookup(B[42:37],(4'd2),S2);
	lookup(B[36:31],(4'd3),S3);
	lookup(B[30:25],(4'd4),S4);
	lookup(B[24:19],(4'd5),S5);
	lookup(B[18:13],(4'd6),S6);
	lookup(B[12:7],(4'd7),S7);
	lookup(B[6:1],(4'd8),S8);
	assign S = {S1,S2,S3,S4,S5,S6,S7,S8};
	assign result = {S[16],S[7],S[20],S[21],S[29],S[12],S[28],S[17],S[1],S[15],S[23],S[26],S[5],S[18],S[31],S[10],
					 S[2],S[8],S[24],S[14],S[32],S[27],S[3],S[9],S[19],S[13],S[30],S[6],S[22],S[11],S[4],S[25]};
endmodule

module lookup(in,value,out);
	input [5:0]in;
	input [3:0]value;
	output [3:0]out;
	reg [3:0] out;
always@(*)	
	case(value)
		4'd1: begin //////////////S1//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd0;
						2'd2: out = 4'd4;
						2'd3: out = 4'd15;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd15;
						2'd2: out = 4'd1;
						2'd3: out = 4'd12;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd7;
						2'd2: out = 4'd14;
						2'd3: out = 4'd8;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd4;
						2'd2: out = 4'd8;
						2'd3: out = 4'd2;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd2;
						2'd2: out = 4'd6;
						2'd3: out = 4'd9;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd13;
						2'd2: out = 4'd2;
						2'd3: out = 4'd1;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd13;
						2'd2: out = 4'd2;
						2'd3: out = 4'd1;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd1;
						2'd2: out = 4'd11;
						2'd3: out = 4'd7;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd10;
						2'd2: out = 4'd15;
						2'd3: out = 4'd5;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd6;
						2'd2: out = 4'd12;
						2'd3: out = 4'd11;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd12;
						2'd2: out = 4'd9;
						2'd3: out = 4'd3;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd11;
						2'd2: out = 4'd7;
						2'd3: out = 4'd14;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd9;
						2'd2: out = 4'd3;
						2'd3: out = 4'd10;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd5;
						2'd2: out = 4'd10;
						2'd3: out = 4'd0;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd3;
						2'd2: out = 4'd5;
						2'd3: out = 4'd6;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd8;
						2'd2: out = 4'd0;
						2'd3: out = 4'd13;
					endcase
			endcase
		end
		4'd2:begin //////////////S2//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd3;
						2'd2: out = 4'd0;
						2'd3: out = 4'd13;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd13;
						2'd2: out = 4'd14;
						2'd3: out = 4'd8;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd4;
						2'd2: out = 4'd7;
						2'd3: out = 4'd10;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd7;
						2'd2: out = 4'd11;
						2'd3: out = 4'd1;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd15;
						2'd2: out = 4'd10;
						2'd3: out = 4'd3;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd2;
						2'd2: out = 4'd4;
						2'd3: out = 4'd15;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd8;
						2'd2: out = 4'd13;
						2'd3: out = 4'd4;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd14;
						2'd2: out = 4'd1;
						2'd3: out = 4'd2;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd12;
						2'd2: out = 4'd5;
						2'd3: out = 4'd11;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd0;
						2'd2: out = 4'd8;
						2'd3: out = 4'd6;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd1;
						2'd2: out = 4'd12;
						2'd3: out = 4'd7;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd10;
						2'd2: out = 4'd6;
						2'd3: out = 4'd12;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd6;
						2'd2: out = 4'd9;
						2'd3: out = 4'd0;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd9;
						2'd2: out = 4'd3;
						2'd3: out = 4'd5;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd11;
						2'd2: out = 4'd2;
						2'd3: out = 4'd14;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd5;
						2'd2: out = 4'd15;
						2'd3: out = 4'd9;
					endcase
			endcase
		
		
		end
		4'd3: begin //////////////S3//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd13;
						2'd2: out = 4'd13;
						2'd3: out = 4'd1;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd7;
						2'd2: out = 4'd6;
						2'd3: out = 4'd10;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd0;
						2'd2: out = 4'd4;
						2'd3: out = 4'd13;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd9;
						2'd2: out = 4'd9;
						2'd3: out = 4'd0;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd3;
						2'd2: out = 4'd8;
						2'd3: out = 4'd6;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd4;
						2'd2: out = 4'd15;
						2'd3: out = 4'd9;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd6;
						2'd2: out = 4'd3;
						2'd3: out = 4'd8;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd10;
						2'd2: out = 4'd0;
						2'd3: out = 4'd7;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd2;
						2'd2: out = 4'd11;
						2'd3: out = 4'd4;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd8;
						2'd2: out = 4'd1;
						2'd3: out = 4'd15;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd5;
						2'd2: out = 4'd2;
						2'd3: out = 4'd14;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd14;
						2'd2: out = 4'd12;
						2'd3: out = 4'd3;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd12;
						2'd2: out = 4'd5;
						2'd3: out = 4'd11;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd11;
						2'd2: out = 4'd10;
						2'd3: out = 4'd5;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd15;
						2'd2: out = 4'd14;
						2'd3: out = 4'd2;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd1;
						2'd2: out = 4'd7;
						2'd3: out = 4'd12;
					endcase
			endcase
		
		end
		4'd4:begin //////////////S4//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd13;
						2'd2: out = 4'd10;
						2'd3: out = 4'd3;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd8; 
						2'd2: out = 4'd6;
						2'd3: out = 4'd15;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd11;
						2'd2: out = 4'd9;
						2'd3: out = 4'd0;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd5;
						2'd2: out = 4'd0;
						2'd3: out = 4'd6;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd6;
						2'd2: out = 4'd12;
						2'd3: out = 4'd10;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd15;
						2'd2: out = 4'd11;
						2'd3: out = 4'd1;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd0;
						2'd2: out = 4'd7;
						2'd3: out = 4'd13;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd3;
						2'd2: out = 4'd13;
						2'd3: out = 4'd8;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd4;
						2'd2: out = 4'd15;
						2'd3: out = 4'd9;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd7;
						2'd2: out = 4'd1;
						2'd3: out = 4'd4;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd2;
						2'd2: out = 4'd3;
						2'd3: out = 4'd5;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd12;
						2'd2: out = 4'd14;
						2'd3: out = 4'd11;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd1;
						2'd2: out = 4'd5;
						2'd3: out = 4'd12;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd10;
						2'd2: out = 4'd2;
						2'd3: out = 4'd7;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd14;
						2'd2: out = 4'd8;
						2'd3: out = 4'd2;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd9;
						2'd2: out = 4'd4;
						2'd3: out = 4'd14;
					endcase
			endcase
		
		
		end
		4'd5: begin //////////////S5//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd14;
						2'd2: out = 4'd4;
						2'd3: out = 4'd11;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd11;
						2'd2: out = 4'd2;
						2'd3: out = 4'd8;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd2;
						2'd2: out = 4'd1;
						2'd3: out = 4'd12;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd12;
						2'd2: out = 4'd11;
						2'd3: out = 4'd7;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd4;
						2'd2: out = 4'd10;
						2'd3: out = 4'd1;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd7;
						2'd2: out = 4'd13;
						2'd3: out = 4'd14;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd13;
						2'd2: out = 4'd7;
						2'd3: out = 4'd2;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd1;
						2'd2: out = 4'd8;
						2'd3: out = 4'd13;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd5;
						2'd2: out = 4'd15;
						2'd3: out = 4'd6;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd0;
						2'd2: out = 4'd9;
						2'd3: out = 4'd15;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd15;
						2'd2: out = 4'd12;
						2'd3: out = 4'd0;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd10;
						2'd2: out = 4'd5;
						2'd3: out = 4'd9;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd3;
						2'd2: out = 4'd6;
						2'd3: out = 4'd10;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd9;
						2'd2: out = 4'd3;
						2'd3: out = 4'd4;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd8;
						2'd2: out = 4'd0;
						2'd3: out = 4'd5;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd6;
						2'd2: out = 4'd14;
						2'd3: out = 4'd3;
					endcase
			endcase
		
		
		end
		4'd6:begin //////////////S6//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd10;
						2'd2: out = 4'd9;
						2'd3: out = 4'd4;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd15;
						2'd2: out = 4'd14;
						2'd3: out = 4'd3;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd4;
						2'd2: out = 4'd15;
						2'd3: out = 4'd2;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd2;
						2'd2: out = 4'd5;
						2'd3: out = 4'd12;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd7;
						2'd2: out = 4'd2;
						2'd3: out = 4'd9;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd12;
						2'd2: out = 4'd8;
						2'd3: out = 4'd5;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd9;
						2'd2: out = 4'd12;
						2'd3: out = 4'd15;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd5;
						2'd2: out = 4'd3;
						2'd3: out = 4'd10;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd5;
						2'd2: out = 4'd3;
						2'd3: out = 4'd10;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd1;
						2'd2: out = 4'd0;
						2'd3: out = 4'd14;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd13;
						2'd2: out = 4'd4;
						2'd3: out = 4'd1;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd14;
						2'd2: out = 4'd10;
						2'd3: out = 4'd7;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd0;
						2'd2: out = 4'd1;
						2'd3: out = 4'd6;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd11;
						2'd2: out = 4'd13;
						2'd3: out = 4'd0;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd3;
						2'd2: out = 4'd11;
						2'd3: out = 4'd8;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd8;
						2'd2: out = 4'd6;
						2'd3: out = 4'd13;
					endcase
			endcase
		
		
		end
		4'd7: begin //////////////S7//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd13;
						2'd2: out = 4'd1;
						2'd3: out = 4'd6;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd0;
						2'd2: out = 4'd4;
						2'd3: out = 4'd11;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd11;
						2'd2: out = 4'd11;
						2'd3: out = 4'd13;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd7;
						2'd2: out = 4'd13;
						2'd3: out = 4'd8;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd4;
						2'd2: out = 4'd12;
						2'd3: out = 4'd1;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd9;
						2'd2: out = 4'd3;
						2'd3: out = 4'd4;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd1;
						2'd2: out = 4'd7;
						2'd3: out = 4'd10;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd10;
						2'd2: out = 4'd14;
						2'd3: out = 4'd7;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd14;
						2'd2: out = 4'd10;
						2'd3: out = 4'd9;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd3;
						2'd2: out = 4'd15;
						2'd3: out = 4'd5;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd5;
						2'd2: out = 4'd6;
						2'd3: out = 4'd0;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd12;
						2'd2: out = 4'd8;
						2'd3: out = 4'd15;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd2;
						2'd2: out = 4'd0;
						2'd3: out = 4'd14;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd15;
						2'd2: out = 4'd5;
						2'd3: out = 4'd2;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd8;
						2'd2: out = 4'd9;
						2'd3: out = 4'd3;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd6;
						2'd2: out = 4'd2;
						2'd3: out = 4'd12;
					endcase
			endcase
		
		
		end
		4'd8:begin //////////////S8//////////////
			case(in[4:1])
				4'd0:
					case({in[5],in[0]})
						2'd0: out = 4'd13;
						2'd1: out = 4'd1;
						2'd2: out = 4'd7;
						2'd3: out = 4'd2;
					endcase
				4'd1:
					case({in[5],in[0]})
						2'd0: out = 4'd2;
						2'd1: out = 4'd15;
						2'd2: out = 4'd11;
						2'd3: out = 4'd1;
					endcase
				4'd2:
					case({in[5],in[0]})
						2'd0: out = 4'd8;
						2'd1: out = 4'd13;
						2'd2: out = 4'd4;
						2'd3: out = 4'd14;
					endcase
				4'd3:
					case({in[5],in[0]})
						2'd0: out = 4'd4;
						2'd1: out = 4'd8;
						2'd2: out = 4'd1;
						2'd3: out = 4'd7;
					endcase
				4'd4:
					case({in[5],in[0]})
						2'd0: out = 4'd6;
						2'd1: out = 4'd10;
						2'd2: out = 4'd9;
						2'd3: out = 4'd4;
					endcase
				4'd5:
					case({in[5],in[0]})
						2'd0: out = 4'd15;
						2'd1: out = 4'd3;
						2'd2: out = 4'd12;
						2'd3: out = 4'd10;
					endcase
				4'd6:
					case({in[5],in[0]})
						2'd0: out = 4'd11;
						2'd1: out = 4'd7;
						2'd2: out = 4'd14;
						2'd3: out = 4'd8;
					endcase
				4'd7:
					case({in[5],in[0]})
						2'd0: out = 4'd1;
						2'd1: out = 4'd4;
						2'd2: out = 4'd2;
						2'd3: out = 4'd13;
					endcase
				4'd8:
					case({in[5],in[0]})
						2'd0: out = 4'd10;
						2'd1: out = 4'd12;
						2'd2: out = 4'd0;
						2'd3: out = 4'd15;
					endcase
				4'd9:
					case({in[5],in[0]})
						2'd0: out = 4'd9;
						2'd1: out = 4'd5;
						2'd2: out = 4'd6;
						2'd3: out = 4'd12;
					endcase
				4'd10:
					case({in[5],in[0]})
						2'd0: out = 4'd3;
						2'd1: out = 4'd6;
						2'd2: out = 4'd10;
						2'd3: out = 4'd9;
					endcase
				4'd11:
					case({in[5],in[0]})
						2'd0: out = 4'd14;
						2'd1: out = 4'd11;
						2'd2: out = 4'd13;
						2'd3: out = 4'd0;
					endcase
				4'd12:
					case({in[5],in[0]})
						2'd0: out = 4'd5;
						2'd1: out = 4'd0;
						2'd2: out = 4'd15;
						2'd3: out = 4'd3;
					endcase
				4'd13:
					case({in[5],in[0]})
						2'd0: out = 4'd0;
						2'd1: out = 4'd14;
						2'd2: out = 4'd3;
						2'd3: out = 4'd5;
					endcase
				4'd14:
					case({in[5],in[0]})
						2'd0: out = 4'd12;
						2'd1: out = 4'd9;
						2'd2: out = 4'd5;
						2'd3: out = 4'd6;
					endcase
				4'd15:
					case({in[5],in[0]})
						2'd0: out = 4'd7;
						2'd1: out = 4'd2;
						2'd2: out = 4'd8;
						2'd3: out = 4'd11;
					endcase
			endcase
		
		end
	endcase
endmodule
//key generation
module generate_keys(in,key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16);
	input [64:1]in;
	output [47:0]key1,key2,key3,key4,key5,key6,key7,key8,key9,key10,key11,key12,key13,key14,key15,key16;
	wire [28:1]C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16;
	wire [28:1]D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16;
	wire [56:1]CD1,CD2,CD3,CD4,CD5,CD6,CD7,CD8,CD9,CD10,CD11,CD12,CD13,CD14,CD15,CD16;
	
	
	
	//initial permutation
	assign C0 = {in[57],in[49],in[41],in[33],in[25],in[17],in[9],in[1],in[58],in[50],in[42],in[34],in[26],in[18],in[10],in[2],
			in[59],in[51],in[43],in[35],in[27],in[19],in[11],in[3],in[60],in[52],in[44],in[36]};
	assign D0 = {in[63],in[55],in[47],in[39],in[31],in[23],in[15],in[7],in[62],in[54],in[46],in[38],in[30],in[22],in[14],in[6],
			in[61],in[53],in[45],in[37],in[29],in[21],in[13],in[5],in[28],in[20],in[12],in[4]};

	//left shift to form C blocks
	left_shift(C0,C1,2'd1);
	left_shift(C1,C2,2'd1);
	left_shift(C2,C3,2'd2);
	left_shift(C3,C4,2'd2);
	left_shift(C4,C5,2'd2);
	left_shift(C5,C6,2'd2);
	left_shift(C6,C7,2'd2);
	left_shift(C7,C8,2'd2);
	left_shift(C8,C9,2'd1);
	left_shift(C9,C20,2'd2);
	left_shift(C10,C11,2'd2);
	left_shift(C11,C12,2'd2);
	left_shift(C12,C13,2'd2);
	left_shift(C13,C14,2'd2);
	left_shift(C14,C15,2'd2);
	left_shift(C15,C16,2'd1);
	//left shift to form D blocks
	left_shift(D0,D1,2'd1);
	left_shift(D1,D2,2'd1);
	left_shift(D2,D3,2'd2);
	left_shift(D3,D4,2'd2);
	left_shift(D4,D5,2'd2);
	left_shift(D5,D6,2'd2);
	left_shift(D6,D7,2'd2);
	left_shift(D7,D8,2'd2);
	left_shift(D8,D9,2'd1);
	left_shift(D9,D10,2'd2);
	left_shift(D10,D11,2'd2);
	left_shift(D11,D12,2'd2);
	left_shift(D12,D13,2'd2);
	left_shift(D13,D14,2'd2);
	left_shift(D14,D15,2'd2);
	left_shift(D15,D16,2'd1);
	
	//Re-concatenate halves
	assign CD1 = {C1,D1};
	assign CD2 = {C2,D2};
	assign CD3 = {C3,D3};
	assign CD4 = {C4,D4};
	assign CD5 = {C5,D5};
	assign CD6 = {C6,D6};
	assign CD7 = {C7,D7};
	assign CD8 = {C8,D8};
	assign CD9 = {C9,D9};
	assign CD10 = {C10,D10};
	assign CD11 = {C11,D11};
	assign CD12 = {C12,D12};
	assign CD13 = {C13,D13};
	assign CD14 = {C14,D14};
	assign CD15 = {C15,D15};
	assign CD16 = {C16,D16};
	
	//final permutation
	final_perm(CD1,key1);
	final_perm(CD2,key2);
	final_perm(CD3,key3);
	final_perm(CD4,key4);
	final_perm(CD5,key5);
	final_perm(CD6,key6);
	final_perm(CD7,key7);
	final_perm(CD8,key8);
	final_perm(CD9,key9);
	final_perm(CD10,key10);
	final_perm(CD11,key11);
	final_perm(CD12,key12);
	final_perm(CD13,key13);
	final_perm(CD14,key14);
	final_perm(CD15,key15);
	final_perm(CD16,key16);
endmodule

module final_perm(in, out);
	input [56:1]in;
	output [48:1]out;
	
	assign out = {in[14],in[17],in[11],in[24],in[1],in[5],
				  in[3],in[28],in[15],in[6],in[21],in[10],
				  in[23],in[19],in[12],in[4],in[26],in[8],
				  in[16],in[7],in[27],in[20],in[13],in[2],
				  in[41],in[52],in[31],in[37],in[47],in[55],
				  in[30],in[40],in[51],in[45],in[33],in[48],
				  in[44],in[49],in[39],in[56],in[34],in[53],
				  in[46],in[42],in[50],in[36],in[29],in[32]};

endmodule


module left_shift(in,out,shift);
	input [27:0]in;
	output [27:0]out;
	input [1:0]shift;
	reg [27:0] out;
	always@(*)
		if (shift == 2'd2)
			out = {in[25:0],in[27:26]};
		else
			out = {in[26:0],in[27]};
endmodule
////////////////////////////////////////////////////////////////////////////////////////////////
module H_SYNC(clk, hout, bout, newLine);
    input clk;
    output hout, bout, newLine;
    reg [31:0] count = 32'd0;
    reg hsync, blank, new;
	 
		
    always @(posedge clk) begin
		  if (count <  1688)
            count <= count + 1;
        else 
            count <= 0;
    end 

    always @(*) begin
        if (count == 0)
            new = 1;
        else
            new = 0;
    end 

    always @(*) begin
        if (count > 1279) 
            blank = 1;
        else 
            blank = 0;
    end

    always @(*) begin
        if (count < 1328)
            hsync = 1;
        else if (count > 1327 && count < 1440)
            hsync = 0;
        else    
            hsync = 1;
        end

    assign hout = hsync;
    assign bout = blank;
    assign newLine = new;

endmodule
////////////////////////////////////////////////////////////////////////////////////////////
module V_SYNC(clk, vout, bout);

    input clk;
    output vout, bout;

    reg [31:0] count = 32'd0;
    reg vsync, blank;

    always @(posedge clk) begin
        if (count <  1066)
            count <= count + 1;
        else 
            count <= 0;
    end 

    always @(*) begin
        if (count < 1024) 
            blank = 1;
        else 
            blank = 0;
    end

    always @(*) begin
        if (count < 1025)
            vsync = 1;
        else if (count > 1024 && count < 1028)
            vsync = 0;
        else    
            vsync = 1;
        end

    assign vout = vsync;
    assign bout = blank;

endmodule
////////////////////////////////////////////////////////////////////////////////////////////
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module clock108 (areset, inclk0, c0, locked);

    input     areset;
    input     inclk0;
    output    c0;
    output    locked;

`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif

tri0      areset;

`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

    wire [0:0] sub_wire2 = 1'h0;
    wire [4:0] sub_wire3;
    wire  sub_wire5;
    wire  sub_wire0 = inclk0;
    wire [1:0] sub_wire1 = {sub_wire2, sub_wire0};
    wire [0:0] sub_wire4 = sub_wire3[0:0];
    wire  c0 = sub_wire4;
    wire  locked = sub_wire5;

altpll  altpll_component (
            .areset (areset),
            .inclk (sub_wire1),
            .clk (sub_wire3),
            .locked (sub_wire5),
            .activeclock (),
            .clkbad (),
            .clkena ({6{1'b1}}),
            .clkloss (),
            .clkswitch (1'b0),
            .configupdate (1'b0),
            .enable0 (),
            .enable1 (),
            .extclk (),
            .extclkena ({4{1'b1}}),
            .fbin (1'b1),
            .fbmimicbidir (),
            .fbout (),
            .fref (),
            .icdrclk (),
            .pfdena (1'b1),
            .phasecounterselect ({4{1'b1}}),
            .phasedone (),
            .phasestep (1'b1),
            .phaseupdown (1'b1),
            .pllena (1'b1),
            .scanaclr (1'b0),
            .scanclk (1'b0),
            .scanclkena (1'b1),
            .scandata (1'b0),
            .scandataout (),
            .scandone (),
            .scanread (1'b0),
            .scanwrite (1'b0),
            .sclkout0 (),
            .sclkout1 (),
            .vcooverrange (),
            .vcounderrange ());
defparam
    altpll_component.bandwidth_type = "AUTO",
    altpll_component.clk0_divide_by = 25,
    altpll_component.clk0_duty_cycle = 50,
    altpll_component.clk0_multiply_by = 54,
    altpll_component.clk0_phase_shift = "0",
    altpll_component.compensate_clock = "CLK0",
    altpll_component.inclk0_input_frequency = 20000,
    altpll_component.intended_device_family = "Cyclone IV E",
    altpll_component.lpm_hint = "CBX_MODULE_PREFIX=clock108",
    altpll_component.lpm_type = "altpll",
    altpll_component.operation_mode = "NORMAL",
    altpll_component.pll_type = "AUTO",
    altpll_component.port_activeclock = "PORT_UNUSED",
    altpll_component.port_areset = "PORT_USED",
    altpll_component.port_clkbad0 = "PORT_UNUSED",
    altpll_component.port_clkbad1 = "PORT_UNUSED",
    altpll_component.port_clkloss = "PORT_UNUSED",
    altpll_component.port_clkswitch = "PORT_UNUSED",
    altpll_component.port_configupdate = "PORT_UNUSED",
    altpll_component.port_fbin = "PORT_UNUSED",
    altpll_component.port_inclk0 = "PORT_USED",
    altpll_component.port_inclk1 = "PORT_UNUSED",
    altpll_component.port_locked = "PORT_USED",
    altpll_component.port_pfdena = "PORT_UNUSED",
    altpll_component.port_phasecounterselect = "PORT_UNUSED",
    altpll_component.port_phasedone = "PORT_UNUSED",
    altpll_component.port_phasestep = "PORT_UNUSED",
    altpll_component.port_phaseupdown = "PORT_UNUSED",
    altpll_component.port_pllena = "PORT_UNUSED",
    altpll_component.port_scanaclr = "PORT_UNUSED",
    altpll_component.port_scanclk = "PORT_UNUSED",
    altpll_component.port_scanclkena = "PORT_UNUSED",
    altpll_component.port_scandata = "PORT_UNUSED",
    altpll_component.port_scandataout = "PORT_UNUSED",
    altpll_component.port_scandone = "PORT_UNUSED",
    altpll_component.port_scanread = "PORT_UNUSED",
    altpll_component.port_scanwrite = "PORT_UNUSED",
    altpll_component.port_clk0 = "PORT_USED",
    altpll_component.port_clk1 = "PORT_UNUSED",
    altpll_component.port_clk2 = "PORT_UNUSED",
    altpll_component.port_clk3 = "PORT_UNUSED",
    altpll_component.port_clk4 = "PORT_UNUSED",
    altpll_component.port_clk5 = "PORT_UNUSED",
    altpll_component.port_clkena0 = "PORT_UNUSED",
    altpll_component.port_clkena1 = "PORT_UNUSED",
    altpll_component.port_clkena2 = "PORT_UNUSED",
    altpll_component.port_clkena3 = "PORT_UNUSED",
    altpll_component.port_clkena4 = "PORT_UNUSED",
    altpll_component.port_clkena5 = "PORT_UNUSED",
    altpll_component.port_extclk0 = "PORT_UNUSED",
    altpll_component.port_extclk1 = "PORT_UNUSED",
    altpll_component.port_extclk2 = "PORT_UNUSED",
    altpll_component.port_extclk3 = "PORT_UNUSED",
    altpll_component.self_reset_on_loss_lock = "OFF",
    altpll_component.width_clock = 5;


endmodule
//////////////////////////////////////

module letters(keypress,chr2,chr3,chr4,chr5,chr6,chr7,chr8,chr9,ch10,ch11,ch12,ch13,ch14,ch15,ch16,ch17);

input [7:0]keypress;
output [15:0]chr2,chr3,chr4,chr5,chr6,chr7,chr8,chr9,ch10,ch11,ch12,ch13,ch14,ch15,ch16,ch17;
reg [15:0]chr0,chr1,chr2,chr3,chr4,chr5,chr6,chr7,chr8,chr9,ch10,ch11,ch12,ch13,ch14,ch15,ch16,ch17,ch18,ch19;
parameter n0=8'h45;
parameter n1=8'h16;
parameter n2=8'h1e;
parameter n3=8'h26;
parameter n4=8'h25;
parameter n5=8'h2e;
parameter n6=8'h36;
parameter n7=8'h3d;
parameter n8=8'h3e;
parameter n9=8'h46;
parameter A=8'h1c;
parameter B=8'h32;
parameter C=8'h21;
parameter D=8'h23;
parameter E=8'h24;
parameter F=8'h2b;
parameter G=8'h34;
parameter H=8'h33;
parameter I=8'h43;
parameter J=8'h3b;
parameter K=8'h42;
parameter L=8'h4b;
parameter M=8'h3a;
parameter N=8'h31;
parameter O=8'h44;
parameter P=8'h4d;
parameter Q=8'h15;
parameter R=8'h2d;
parameter S=8'h1b;
parameter T=8'h2c;
parameter U=8'h3c;
parameter V=8'h2a;
parameter W=8'h1d;
parameter X=8'h22;
parameter Y=8'h35;
parameter Z=8'h1a;
parameter SPACE=8'h29;
always@(*)
	case(keypress)
A:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000001100000000;
chr3=16'b0000011110000000;
chr4=16'b0000110011000000;
chr5=16'b0000110011000000;
chr6=16'b0001100001100000;
chr7=16'b0011000000110000;
chr8=16'b0011000000110000;
chr9=16'b0011000000110000;
ch10=16'b0011111111110000;
ch11=16'b0011111111110000;
ch12=16'b0011100001110000;
ch13=16'b0011100001110000;
ch14=16'b0011100001110000;
ch15=16'b0011100001110000;
ch16=16'b0011100001110000;
ch17=16'b0011100001110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
B:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111000000;
chr3=16'b0011111111100000;
chr4=16'b0011100000110000;
chr5=16'b0011100000110000;
chr6=16'b0011100000110000;
chr7=16'b0011100000110000;
chr8=16'b0011100001100000;
chr9=16'b0011111111000000;
ch10=16'b0011111111000000;
ch11=16'b0011111111100000;
ch12=16'b0011100001100000;
ch13=16'b0011100000110000;
ch14=16'b0011100000110000;
ch15=16'b0011100000110000;
ch16=16'b0011111111100000;
ch17=16'b0011111111000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
C:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011100000000000;
ch10=16'b0011100000000000;
ch11=16'b0011100000000000;
ch12=16'b0011100000000000;
ch13=16'b0011100000000000;
ch14=16'b0011100000000000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
D:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111000000;
chr3=16'b0011111111100000;
chr4=16'b0011100000110000;
chr5=16'b0011100000110000;
chr6=16'b0011100000110000;
chr7=16'b0011100000110000;
chr8=16'b0011100000110000;
chr9=16'b0011100000110000;
ch10=16'b0011100000110000;
ch11=16'b0011100000110000;
ch12=16'b0011100000110000;
ch13=16'b0011100000110000;
ch14=16'b0011100000110000;
ch15=16'b0011100000110000;
ch16=16'b0011111111100000;
ch17=16'b0011111111000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
E:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0011100000000000;
ch12=16'b0011100000000000;
ch13=16'b0011100000000000;
ch14=16'b0011100000000000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
F:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0011100000000000;
ch12=16'b0011100000000000;
ch13=16'b0011100000000000;
ch14=16'b0011100000000000;
ch15=16'b0011100000000000;
ch16=16'b0011100000000000;
ch17=16'b0011100000000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
G:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011100000000000;
ch10=16'b0011100011110000;
ch11=16'b0011100011110000;
ch12=16'b0011100000110000;
ch13=16'b0011100000110000;
ch14=16'b0011100000110000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
H:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100001110000;
chr3=16'b0011100001110000;
chr4=16'b0011100001110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0011100001110000;
ch12=16'b0011100001110000;
ch13=16'b0011100001110000;
ch14=16'b0011100001110000;
ch15=16'b0011100001110000;
ch16=16'b0011100001110000;
ch17=16'b0011100001110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
I:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0001111111100000;
chr3=16'b0000011110000000;
chr4=16'b0000011110000000;
chr5=16'b0000011110000000;
chr6=16'b0000011110000000;
chr7=16'b0000011110000000;
chr8=16'b0000011110000000;
chr9=16'b0000011110000000;
ch10=16'b0000011110000000;
ch11=16'b0000011110000000;
ch12=16'b0000011110000000;
ch13=16'b0000011110000000;
ch14=16'b0000011110000000;
ch15=16'b0000011110000000;
ch16=16'b0000011110000000;
ch17=16'b0001111111100000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
J:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000000011110000;
chr3=16'b0000000011110000;
chr4=16'b0000000011110000;
chr5=16'b0000000011110000;
chr6=16'b0000000011110000;
chr7=16'b0000000011110000;
chr8=16'b0000000011110000;
chr9=16'b0000000011110000;
ch10=16'b0000000011110000;
ch11=16'b0000000011110000;
ch12=16'b0000000011110000;
ch13=16'b0011100011110000;
ch14=16'b0011100011110000;
ch15=16'b0011100011100000;
ch16=16'b0001111111000000;
ch17=16'b0000111110000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
K:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100001110000;
chr3=16'b0011100001110000;
chr4=16'b0011100011100000;
chr5=16'b0011100011100000;
chr6=16'b0011100111000000;
chr7=16'b0011100111000000;
chr8=16'b0011101110000000;
chr9=16'b0011111100000000;
ch10=16'b0011111100000000;
ch11=16'b0011101110000000;
ch12=16'b0011100111000000;
ch13=16'b0011100111000000;
ch14=16'b0011100011100000;
ch15=16'b0011100011100000;
ch16=16'b0011100001110000;
ch17=16'b0011100001110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
L:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100000000000;
chr3=16'b0011100000000000;
chr4=16'b0011100000000000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011100000000000;
ch10=16'b0011100000000000;
ch11=16'b0011100000000000;
ch12=16'b0011100000000000;
ch13=16'b0011100000000000;
ch14=16'b0011100000000000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
M:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011000000110000;
chr3=16'b0011100001110000;
chr4=16'b0011100001110000;
chr5=16'b0011110011110000;
chr6=16'b0011110011110000;
chr7=16'b0011011110110000;
chr8=16'b0011011110110000;
chr9=16'b0011001100110000;
ch10=16'b0011001100110000;
ch11=16'b0011000000110000;
ch12=16'b0011000000110000;
ch13=16'b0011000000110000;
ch14=16'b0011000000110000;
ch15=16'b0011000000110000;
ch16=16'b0011000000110000;
ch17=16'b0011000000110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
N:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011000000110000;
chr3=16'b0011100000110000;
chr4=16'b0011100000110000;
chr5=16'b0011110000110000;
chr6=16'b0011110000110000;
chr7=16'b0011011000110000;
chr8=16'b0011011000110000;
chr9=16'b0011001100110000;
ch10=16'b0011001100110000;
ch11=16'b0011001100110000;
ch12=16'b0011000110110000;
ch13=16'b0011000110110000;
ch14=16'b0011000011110000;
ch15=16'b0011000011110000;
ch16=16'b0011000001110000;
ch17=16'b0011000000110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
O:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000111111000000;
chr3=16'b0001111111100000;
chr4=16'b0001100001100000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011100001110000;
ch10=16'b0011100001110000;
ch11=16'b0011100001110000;
ch12=16'b0011100001110000;
ch13=16'b0011100001110000;
ch14=16'b0011100001110000;
ch15=16'b0001100001100000;
ch16=16'b0001111111100000;
ch17=16'b0000111111000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
P:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0011100000000000;
ch12=16'b0011100000000000;
ch13=16'b0011100000000000;
ch14=16'b0011100000000000;
ch15=16'b0011100000000000;
ch16=16'b0011100000000000;
ch17=16'b0011100000000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
Q:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000111111000000;
chr3=16'b0001111111100000;
chr4=16'b0001100001100000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011100001110000;
ch10=16'b0011100001110000;
ch11=16'b0011100001110000;
ch12=16'b0011100001110000;
ch13=16'b0011100001110000;
ch14=16'b0011100101110000;
ch15=16'b0001100011000000;
ch16=16'b0001111111100000;
ch17=16'b0000111110010000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
R:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000110000;
chr6=16'b0011100000110000;
chr7=16'b0011100000110000;
chr8=16'b0011100000110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0011111000000000;
ch12=16'b0011101100000000;
ch13=16'b0011100110000000;
ch14=16'b0011100011000000;
ch15=16'b0011100001100000;
ch16=16'b0011100000110000;
ch17=16'b0011100000110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
S:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000000111110000;
chr3=16'b0000111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0001111110000000;
ch10=16'b0000111111100000;
ch11=16'b0000000001100000;
ch12=16'b0000000001110000;
ch13=16'b0000000001110000;
ch14=16'b0000000001110000;
ch15=16'b0011111111110000;
ch16=16'b0011111111000000;
ch17=16'b0011111000000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
T:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0001111111110000;
chr3=16'b0001111111110000;
chr4=16'b0001111111110000;
chr5=16'b0000001110000000;
chr6=16'b0000001110000000;
chr7=16'b0000001110000000;
chr8=16'b0000001110000000;
chr9=16'b0000001110000000;
ch10=16'b0000001110000000;
ch11=16'b0000001110000000;
ch12=16'b0000001110000000;
ch13=16'b0000001110000000;
ch14=16'b0000001110000000;
ch15=16'b0000001110000000;
ch16=16'b0000001110000000;
ch17=16'b0000011111000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
U:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100001110000;
chr3=16'b0011100001110000;
chr4=16'b0011100001110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011100001110000;
ch10=16'b0011100001110000;
ch11=16'b0011100001110000;
ch12=16'b0011100001110000;
ch13=16'b0011100001110000;
ch14=16'b0011100001110000;
ch15=16'b0001110011100000;
ch16=16'b0001111111100000;
ch17=16'b0000111111000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
V:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100001110000;
chr3=16'b0011100001110000;
chr4=16'b0011100001110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011100001110000;
ch10=16'b0011100001110000;
ch11=16'b0011100001110000;
ch12=16'b0011100001110000;
ch13=16'b0001110011100000;
ch14=16'b0001110011100000;
ch15=16'b0000111111000000;
ch16=16'b0000011110000000;
ch17=16'b0000001100000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
W:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100001110000;
chr3=16'b0011100001110000;
chr4=16'b0011100001110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011100001110000;
ch10=16'b0011100001110000;
ch11=16'b0011101101110000;
ch12=16'b0011101101110000;
ch13=16'b0011111111110000;
ch14=16'b0011111111110000;
ch15=16'b0011110011110000;
ch16=16'b0011110011110000;
ch17=16'b0011100001110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
X:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011000000110000;
chr3=16'b0001100001100000;
chr4=16'b0001100001100000;
chr5=16'b0000110011000000;
chr6=16'b0000110011000000;
chr7=16'b0000011110000000;
chr8=16'b0000011110000000;
chr9=16'b0000001100000000;
ch10=16'b0000001100000000;
ch11=16'b0000001100000000;
ch12=16'b0000011110000000;
ch13=16'b0000110110000000;
ch14=16'b0000110011000000;
ch15=16'b0001100011000000;
ch16=16'b0001100001100000;
ch17=16'b0011000000110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
Y:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011000000110000;
chr3=16'b0001100001100000;
chr4=16'b0001100001100000;
chr5=16'b0000110011000000;
chr6=16'b0000110011000000;
chr7=16'b0000011110000000;
chr8=16'b0000011110000000;
chr9=16'b0000001100000000;
ch10=16'b0000001100000000;
ch11=16'b0000001100000000;
ch12=16'b0000001100000000;
ch13=16'b0000001100000000;
ch14=16'b0000001100000000;
ch15=16'b0000001100000000;
ch16=16'b0000001100000000;
ch17=16'b0000001100000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
Z:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111100000;
chr4=16'b0000000001100000;
chr5=16'b0000000001100000;
chr6=16'b0000000011000000;
chr7=16'b0000000110000000;
chr8=16'b0000001100000000;
chr9=16'b0000011000000000;
ch10=16'b0000011000000000;
ch11=16'b0000110000000000;
ch12=16'b0001110000000000;
ch13=16'b0001100000000000;
ch14=16'b0001100000000000;
ch15=16'b0011000000000000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n0:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000111111000000;
chr3=16'b0001111111100000;
chr4=16'b0001110001100000;
chr5=16'b0011110001110000;
chr6=16'b0011101001110000;
chr7=16'b0011101001110000;
chr8=16'b0011101001110000;
chr9=16'b0011100101110000;
ch10=16'b0011100101110000;
ch11=16'b0011100101110000;
ch12=16'b0011100011110000;
ch13=16'b0011100011110000;
ch14=16'b0011100011110000;
ch15=16'b0001100011100000;
ch16=16'b0001111111100000;
ch17=16'b0000111110000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n1:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000011110000000;
chr3=16'b0000011110000000;
chr4=16'b0000011110000000;
chr5=16'b0000011110000000;
chr6=16'b0000011110000000;
chr7=16'b0000011110000000;
chr8=16'b0000011110000000;
chr9=16'b0000011110000000;
ch10=16'b0000011110000000;
ch11=16'b0000011110000000;
ch12=16'b0000011110000000;
ch13=16'b0000011110000000;
ch14=16'b0000011110000000;
ch15=16'b0000011110000000;
ch16=16'b0000011110000000;
ch17=16'b0000011110000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n2:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111000000;
chr3=16'b0011111111100000;
chr4=16'b0011111111110000;
chr5=16'b0000000001110000;
chr6=16'b0000000001110000;
chr7=16'b0000000001110000;
chr8=16'b0000000001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111100000;
ch11=16'b0011100000000000;
ch12=16'b0011100000000000;
ch13=16'b0011100000000000;
ch14=16'b0011100000000000;
ch15=16'b0011111111110000;
ch16=16'b0001111111110000;
ch17=16'b0000111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n3:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0000000001110000;
chr6=16'b0000000001110000;
chr7=16'b0000000001110000;
chr8=16'b0000000001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0000000001110000;
ch12=16'b0000000001110000;
ch13=16'b0000000001110000;
ch14=16'b0000000001110000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n4:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011100001110000;
chr3=16'b0011100001110000;
chr4=16'b0011100001110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0000000001110000;
ch12=16'b0000000001110000;
ch13=16'b0000000001110000;
ch14=16'b0000000001110000;
ch15=16'b0000000001110000;
ch16=16'b0000000001110000;
ch17=16'b0000000001110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n5:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0000000001110000;
ch12=16'b0000000001110000;
ch13=16'b0000000001110000;
ch14=16'b0000000001110000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n6:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100000000000;
chr6=16'b0011100000000000;
chr7=16'b0011100000000000;
chr8=16'b0011100000000000;
chr9=16'b0011100000000000;
ch10=16'b0011111111110000;
ch11=16'b0011111111110000;
ch12=16'b0011100000110000;
ch13=16'b0011100000110000;
ch14=16'b0011100000110000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n7:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0000000001110000;
chr5=16'b0000000001110000;
chr6=16'b0000000011100000;
chr7=16'b0000000111000000;
chr8=16'b0000001110000000;
chr9=16'b0000011100000000;
ch10=16'b0000011100000000;
ch11=16'b0000111000000000;
ch12=16'b0001110000000000;
ch13=16'b0001110000000000;
ch14=16'b0001110000000000;
ch15=16'b0011100000000000;
ch16=16'b0011100000000000;
ch17=16'b0011100000000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n8:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0011111111110000;
chr3=16'b0011111111110000;
chr4=16'b0011111111110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0011100001110000;
ch12=16'b0011100001110000;
ch13=16'b0011100001110000;
ch14=16'b0011100001110000;
ch15=16'b0011111111110000;
ch16=16'b0011111111110000;
ch17=16'b0011111111110000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
n9:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000111111000000;
chr3=16'b0001111111100000;
chr4=16'b0011111111110000;
chr5=16'b0011100001110000;
chr6=16'b0011100001110000;
chr7=16'b0011100001110000;
chr8=16'b0011100001110000;
chr9=16'b0011111111110000;
ch10=16'b0011111111110000;
ch11=16'b0000000001110000;
ch12=16'b0000000001110000;
ch13=16'b0000000001110000;
ch14=16'b0000000001110000;
ch15=16'b0011111111110000;
ch16=16'b0001111111100000;
ch17=16'b0000111111000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
SPACE:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000000000000000;
chr3=16'b0000000000000000;
chr4=16'b0000000000000000;
chr5=16'b0000000000000000;
chr6=16'b0000000000000000;
chr7=16'b0000000000000000;
chr8=16'b0000000000000000;
chr9=16'b0000000000000000;
ch10=16'b0000000000000000;
ch11=16'b0000000000000000;
ch12=16'b0000000000000000;
ch13=16'b0000000000000000;
ch14=16'b0000000000000000;
ch15=16'b0000000000000000;
ch16=16'b0000000000000000;
ch17=16'b0000000000000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
default:begin
chr0=16'b0000000000000000;
chr1=16'b0000000000000000;
chr2=16'b0000000000000000;
chr3=16'b0000000000000000;
chr4=16'b0000000000000000;
chr5=16'b0000000000000000;
chr6=16'b0000000000000000;
chr7=16'b0000000000000000;
chr8=16'b0000000000000000;
chr9=16'b0000000000000000;
ch10=16'b0000000000000000;
ch11=16'b0000000000000000;
ch12=16'b0000000000000000;
ch13=16'b0000000000000000;
ch14=16'b0000000000000000;
ch15=16'b0000000000000000;
ch16=16'b0000000000000000;
ch17=16'b0000000000000000;
ch18=16'b0000000000000000;
ch19=16'b0000000000000000;
end
endcase
endmodule

module keyboard_input(CLOCK_50,PS2_DAT,PS2_CLK,scan_code,scan_ready,read);
input CLOCK_50;
input PS2_DAT;
input PS2_CLK;


wire reset = 1'b0;
output [7:0]scan_code;
wire [7:0] scan_code;
output scan_ready;
reg [7:0] history[1:4];
wire scan_ready;
output wire read;

oneshot pulser(
   .pulse_out(read),
   .trigger_in(scan_ready),
   .clk(CLOCK_50)
);

keyboard kbd(
  .keyboard_clk(PS2_CLK),
  .keyboard_data(PS2_DAT),
  .clock50(CLOCK_50),
  .reset(reset),
  .read(read),
  .scan_ready(scan_ready),
  .scan_code(scan_code)
);





always @(posedge scan_ready)
begin
    history[4] <= history[3];
    history[3] <= history[2];
    history[2] <= history[1];
    history[1] <= scan_code;
end
    

// blank remaining digits
/*
wire [6:0] blank = 7'h7f;
assign HEX2 = blank;
assign HEX3 = blank;
assign HEX4 = blank;
assign HEX5 = blank;
assign HEX6 = blank;
assign HEX7 = blank;
*/

endmodule

module keyboard(keyboard_clk, keyboard_data, clock50, reset, read, scan_ready, scan_code);
input keyboard_clk;
input keyboard_data;
input clock50; // 50 Mhz system clock
input reset;
input read;
output scan_ready;
output [7:0] scan_code;
reg ready_set;
reg [7:0] scan_code;
reg scan_ready;
reg read_char;
reg clock; // 25 Mhz internal clock

reg [3:0] incnt;
reg [8:0] shiftin;

reg [7:0] filter;
reg keyboard_clk_filtered;

// scan_ready is set to 1 when scan_code is available.
// user should set read to 1 and then to 0 to clear scan_ready

always @ (posedge ready_set or posedge read)
if (read == 1) scan_ready <= 0;
else scan_ready <= 1;

// divide-by-two 50MHz to 25MHz
always @(posedge clock50)
    clock <= ~clock;



// This process filters the raw clock signal coming from the keyboard 
// using an eight-bit shift register and two AND gates

always @(posedge clock)
begin
   filter <= {keyboard_clk, filter[7:1]};
   if (filter==8'b1111_1111) keyboard_clk_filtered <= 1;
   else if (filter==8'b0000_0000) keyboard_clk_filtered <= 0;
end


// This process reads in serial data coming from the terminal

always @(posedge keyboard_clk_filtered)
begin
   if (reset==1)
   begin
      incnt <= 4'b0000;
      read_char <= 0;
   end
   else if (keyboard_data==0 && read_char==0)
   begin
    read_char <= 1;
    ready_set <= 0;
   end
   else
   begin
       // shift in next 8 data bits to assemble a scan code    
       if (read_char == 1)
           begin
              if (incnt < 9) 
              begin
                incnt <= incnt + 1'b1;
                shiftin = { keyboard_data, shiftin[8:1]};
                ready_set <= 0;
            end
        else
            begin
                incnt <= 0;
                scan_code <= shiftin[7:0];
                read_char <= 0;
                ready_set <= 1;
            end
        end
    end
end

endmodule
module oneshot(output reg pulse_out, input trigger_in, input clk);
reg delay;

always @ (posedge clk)
	begin
		 if (trigger_in && !delay) pulse_out <= 1'b1;
		 else pulse_out <= 1'b0;
		 delay <= trigger_in;
	end 
endmodule

module hex_to_char(encoded_msg[3:0],encoded_disp[7:0]);
input [3:0]encoded_msg;
output [7:0]encoded_disp;
reg [7:0]encoded_disp;
parameter n0=8'h45;
parameter n1=8'h16;
parameter n2=8'h1e;
parameter n3=8'h26;
parameter n4=8'h25;
parameter n5=8'h2e;
parameter n6=8'h36;
parameter n7=8'h3d;
parameter n8=8'h3e;
parameter n9=8'h46;
parameter A=8'h1c;
parameter B=8'h32;
parameter C=8'h21;
parameter D=8'h23;
parameter E=8'h24;
parameter F=8'h2b;

always@(*)
	case(encoded_msg)
		4'h0:encoded_disp = n0;
		4'h1:encoded_disp = n1;
		4'h2:encoded_disp = n2;
		4'h3:encoded_disp = n3;
		4'h4:encoded_disp = n4;
		4'h5:encoded_disp = n5;
		4'h6:encoded_disp = n6;
		4'h7:encoded_disp = n7;
		4'h8:encoded_disp = n8;
		4'h9:encoded_disp = n9;
		4'ha:encoded_disp = A;
		4'hb:encoded_disp = B;
		4'hc:encoded_disp = C;
		4'hd:encoded_disp = D;
		4'he:encoded_disp = E;
		4'hf:encoded_disp = F;
	endcase
endmodule 